// Biblotecas estandar
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
// Bibliotecas IPC
#include <sys/types.h>
#include <unistd.h>
// Clases que encapsulan los IPCs
#include "./IPC/Semaphore/Semaphore.h"
#include "./IPC/SharedMemory/ControlDataSharedMemory.h"
#include "./IPC/MessageQueue/TruckDoorInputMessageQueue.h"
#include "./IPC/MessageQueue/TruckDoorOutputMessageQueue.h"
#include "./IPC/MessageQueue/ChargeToTruckMessageQueue.h"


/* Definición de variables estáticas para pasar argumentos a los procesos */
static char param1[16];
static int i;
static char buffer[255];

/* Declaración de Funciones */
void init_IPCs(void);
void crearPuertas();



int main(int argc, char* argv[])
{		
	// Inicializo el entorno
	srand(getpid());
	init_IPCs();

	crearPuertas();
	return 0;
}

void init_IPCs() {

	ControlData data;

	TruckDoorInputMessageQueue truckDoorInputQueueInput = TruckDoorInputMessageQueue();
	truckDoorInputQueueInput.create((char *) DIRECTORY, ID_Q_TRUCK_DOOR_INPUT);
	TruckDoorOutputMessageQueue truckDoorOutputQueue = TruckDoorOutputMessageQueue();
	truckDoorOutputQueue.create((char *) DIRECTORY, ID_Q_TRUCK_DOOR_OUTPUT);
	
	ChargeToTruckMessageQueue chargeToTruckQueue = ChargeToTruckMessageQueue();
	chargeToTruckQueue.create((char *) DIRECTORY, ID_Q_CHARGE_TO_TRUCK);

	Semaphore semControl = Semaphore();	
	if (semControl.createSemaphore((char *) DIRECTORY, ID_SEMCONTROL, 1) != -1) {
		semControl.initializeSemaphore(0, 1);
	}
	
	Semaphore semTruckDoor = Semaphore();
	semTruckDoor.createSemaphore((char *) DIRECTORY, ID_SEMTRUCKDOOR, CANT_DOORS);
	for (int i = 0; i < CANT_DOORS; i++) {
		semTruckDoor.initializeSemaphore(i, 0);
	}
	
	ControlDataSharedMemory shMem = ControlDataSharedMemory();
	if (shMem.createSharedMemory((char *) DIRECTORY, ID_SHMEM) != -1) {
		shMem.write(&data);
		shMem.read(&data);
		//sprintf(buffer, "Proceso LauncherPuertasCamiones - Valor inicial de cantPersonas: %d\n", 
		//data.cantPersonas);
		write(fileno(stdout), buffer, strlen(buffer));
	}

}

void crearPuertas() {
	pid_t pid;

	// Creo las 4 puertas de entrada
	for(i = 1; i <= CANT_DOORS; i++) {
		if ((pid = fork()) < 0) {
			sprintf(buffer, "Launcher Error: %s\n", strerror(errno));
			write(fileno(stdout), buffer, strlen(buffer));
		}				
		else if (pid == 0) {
			// Paso como parámetro a Puerta el número que identifica a 
			// la misma en el Museo (es un autoincrementable)
			sprintf(param1, "%d", i);
			execlp("./puertaCamion", "puertaCamion", param1, (char *) 0);
			sprintf(buffer, "Launcher Error: %s\n", strerror(errno));
			write(fileno(stdout), buffer, strlen(buffer));
		}
	}
}

